package cn.throwx.sc.ch3.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.firewall.FirewalledRequest;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.RequestRejectedException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
import java.util.Set;

/**
 * @author throwable
 * @version v1
 * @description
 * @since 2021/11/8 0:20
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Set<String> BLOCK_URI_SET = new HashSet<>();

    static {
        // 这里加载禁用的URI
        BLOCK_URI_SET.add("/foo");
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 忽略static和resources目录的认证和鉴权
        web.ignoring()
                .antMatchers("/static/**")
                .antMatchers("/resources/**")
                .and()
                .httpFirewall(new HttpFirewall() {
                    @Override
                    public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
                        String requestURI = request.getRequestURI();
                        if (!BLOCK_URI_SET.contains(requestURI)) {
                            return new FirewalledRequest(request) {
                                @Override
                                public void reset() {

                                }
                            };
                        }
                        throw new RequestRejectedException("Block URI = " + requestURI);
                    }

                    @Override
                    public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
                        return response;
                    }
                });
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/**").permitAll()
                .and()
                .authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN")
                .and()
                .formLogin().loginPage("/login");
    }
}
